#pragma once

#include "Game.h"
#include "GameplayState.h"
#include "MainMenuState.h"
#include "PauseState.h"


#include "../wrappers/CSGD_Direct3D.h"
#include "../wrappers/CSGD_DirectInput.h"
#include "../wrappers/CSGD_TextureManager.h"
#include "../wrappers/CSGD_XAudio2.h"
#include "../wrappers/CSGD_EventSystem.h"
#include "../wrappers/CSGD_MessageSystem.h"

#include "ObjectManager.h"
#include "Player.h"
#include "Enemy.h"

#include "Renderer.h"
#include "Camera.h"

#include "CEvent.h"
#include "IMessage.h"
#include "Message.h"
#include "DestroyObjectMessage.h"

#include "../Tiny XML/tinyxml.h"



#include <cassert>






CGameplayState* CGameplayState::GetInstance( void )
{
	static CGameplayState sInstance;
	return &sInstance;
}


CGameplayState::CGameplayState(void)
{
	m_pD3D				= nullptr;
	m_pDI				= nullptr;
	m_pTM				= nullptr;
	m_pXA				= nullptr;
	m_pMS				= nullptr;
	m_pES				= nullptr;
	m_pOM				= nullptr;
	m_pRenderer			= nullptr;


	srand( 0 );
	rand();

	isPause = false;
}


CGameplayState::~CGameplayState(void)
{
}

void CGameplayState::Enter( void )
{
	m_pD3D		= CSGD_Direct3D::GetInstance();
	m_pDI		= CSGD_DirectInput::GetInstance();
	m_pTM		= CSGD_TextureManager::GetInstance();
	m_pXA		= CSGD_XAudio2::GetInstance();
	m_pMS		= CSGD_MessageSystem::GetInstance();
	m_pES		= CSGD_EventSystem::GetInstance();
	m_pOM		= CObjectManager::GetInstance();
	m_pRenderer = CRenderer::GetInstance();
	CCamera::GetInstance()->Initialize( m_pPlayer, CGame::GetInstance()->GetScreenWidth(),
		CGame::GetInstance()->GetScreenHeight() );

	m_pMS->InitMessageSystem( &MessageProc );
	m_pRenderer->Initialize();
	m_pMS->SendMsg( new CMessage( MSG_TEST ) );
	m_pDI->ClearInput();

	isPause = false;
}


void CGameplayState::Exit( void )
{
	assert( m_pMS == CSGD_MessageSystem::GetInstance() && "CGameplayState::Exit() - tried to shutdown uninitialized MessageSystem" );
	assert( m_pES == CSGD_EventSystem::GetInstance() && "CGameplayState::Exit() - tried to shutdown uninitialized MessageSystem" );

	if(isPause == false)
	{
		m_pMS->ShutdownMessageSystem();
		m_pES->ShutdownEventSystem();
		m_pRenderer->Shutdown();
		m_pOM->RemoveAllObjects();
		m_pOM->DeleteInstance();
		m_pRenderer->Shutdown();
		m_pRenderer->DeleteInstance();

		if( m_pPlayer != nullptr )
		{
			m_pPlayer->Release();
			m_pPlayer = nullptr;
		}

		m_pD3D				= nullptr;
		m_pDI				= nullptr;
		m_pTM				= nullptr;
		m_pXA				= nullptr;
		m_pMS				= nullptr;
		m_pES				= nullptr;
		m_pOM				= nullptr;
		m_pRenderer			= nullptr;
	}
}


bool CGameplayState::Input( void )
{
	if( m_pDI->KeyPressed( DIK_ESCAPE ) )
	{
		//Pause the game
		isPause == true;
		CGame::GetInstance()->ChangeState( CPauseState::GetInstance() );

	}
	return true;
}


void CGameplayState::Update( float fElapsedTime )
{
<<<<<<< HEAD
	if(isPause == false)
	{
		m_pMS->ProcessMessages();
		m_pES->ProcessEvents();
		m_pRenderer->HandleCollision();
		m_pOM->UpdateAllObjects( fElapsedTime );
	}
=======
	m_pMS->ProcessMessages();
	m_pES->ProcessEvents();
	m_pRenderer->UpdateLevel();
	m_pRenderer->HandleCollision();
	m_pOM->UpdateAllObjects( fElapsedTime );
>>>>>>> d25ca73a95776a515f8a8f89fe1d3f131c5a805e

}


void CGameplayState::Render( void )
{
	m_pRenderer->RenderScene();
}


void CGameplayState::MessageProc( IMessage* pMsg )
{
	CGameplayState* pSelf = CGameplayState::GetInstance();

	switch( pMsg->GetMessageID() )
	{
	case MSG_DESTROY_OBJECT:
		{
			CDestroyObjectMessage* pDestroyMsg = dynamic_cast< CDestroyObjectMessage* >(pMsg);
			assert( pDestroyMsg != nullptr && "CGameplayState::MessageProc - pDestroyMsg not actually CDestroyObjectMessage*" );
			pSelf->m_pOM->RemoveObject( pDestroyMsg->GetObjectToDestroy() );
		
		}
		break;
	case MSG_TEST:
		{
			pSelf->m_pPlayer = new CPlayer( 300, 50, 70, 1.2f, 250.0f, 0.4f );
			pSelf->m_pOM->AddObject( pSelf->m_pPlayer );
			pSelf->m_pPlayer->SetMoveSpeed( pSelf->m_pPlayer->GetBaseMS() );
			pSelf->m_pPlayer->SetPosition( 100.0, 0.0, 350.0 );

			CEnemy* pEnemy = new CEnemy( 100, 20, 30, 1.0f, 150.0f, 0.2f, 0, 0 );
			pEnemy->SetPosition( 300.0f, 0.0f, 350.0f );
			pEnemy->SetHeight( 50 );
			pEnemy->SetWidth( 50 );
			pSelf->m_pOM->AddObject( pEnemy );
			pEnemy->Release();

		}
		break;
	default:
		assert( false && "CGameplayState::MessageProc - pMsg unknown message type" );
		break;
	}

}

bool CGameplayState::TestXmlOut( const char * szFilename )
{
	TiXmlDocument doc;

	TiXmlDeclaration* pDecl = new TiXmlDeclaration( "1.0", "utf-8", "" );
	doc.LinkEndChild( pDecl );

	TiXmlElement* pRoot = new TiXmlElement( "test_xml" );

	doc.LinkEndChild( pRoot );

	TiXmlElement* pTest = new TiXmlElement( "test_info" );

	pTest->SetAttribute( "score", 9001 );
	pTest->SetDoubleAttribute( "x", 12.0 );
	pTest->SetDoubleAttribute( "y", 42.0 );
	

	TiXmlText* pText = new TiXmlText( "test" );
	pTest->LinkEndChild( pText );
	pRoot->LinkEndChild( pTest );
	assert( pRoot && "TestXmlFail" );
	return doc.SaveFile( szFilename );
}

bool CGameplayState::TestXmlIn( const char * szFilename )
{
	TiXmlDocument doc;

	if( !doc.LoadFile( szFilename ) )
		return false;

	TiXmlElement* pRoot = doc.RootElement();
	if( !pRoot )
		return false;

	TiXmlElement* pTest = pRoot->FirstChildElement( "test_info" );
	while( pTest )
	{
		const char* pText = pTest->GetText();

		if( pText )
		{
			if( strcmp( pText, "test" ) != 0 )
				return false;
		}

		int score;
		double x,y;
		pTest->Attribute( "x", &x );
		pTest->Attribute( "y", &y );
		pTest->Attribute( "score", &score );

		if( x == 12.0 && y == 42.0 && score == 9001 )
			return true;
		else
			return false;
	}
}






